home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
et
/
et3_0-a1.lha
/
et3
/
src
/
WindowPort.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-08-26
|
9KB
|
476 lines
#ifdef __GNUG__
#pragma implementation
#endif
#include "WindowPort.h"
#include "Class.h"
#include "Error.h"
#include "System.h"
#include "WindowSystem.h"
#include "Math.h"
#include "Storage.h"
#include "String.h"
#include "Window.h"
#include "OrdColl.h"
#include "Region.h"
#include "WindowColorMap.h"
//---- WindowPort --------------------------------------------------------------
NewMetaImpl(WindowPort, Port, (TP(win), TE(state), T(lastpos), T(portrect), TP(wcmap)));
WindowPort::WindowPort(Window *bw, WindowType, GrCursor curs)
{
win= bw;
overlay= FALSE;
state= eWsHidden;
cursor= curs;
hascolor= gColor;
inval= 0;
wcmap= 0;
havepushbacktoken= FALSE;
if (gWindowSystem)
gWindowSystem->AddWindow(this);
}
WindowPort::~WindowPort()
{
if (gWindowSystem)
gWindowSystem->RemoveWindow(this);
if (state != eWsClosed) {
state= eWsClosed;
ExitLoop();
SafeDelete(inval);
}
if (wcmap) {
wcmap->Unref();
wcmap= 0;
}
}
//---- Callbacks ---------------------------------------------------------------
void WindowPort::OpenNotify(Rectangle r)
{
portrect= r;
state= eWsShown;
if (win)
win->OpenNotify(r.extent);
}
void WindowPort::CloseNotify()
{
SafeDelete(inval);
state= eWsHidden;
ExitLoop();
if (win)
win->CloseNotify();
gSystem->InnerLoop();
}
void WindowPort::InputNotify(Token *t)
{
if (state != eWsShown)
return;
if (t->Code != eEvtNone && t->Code != eEvtIdle) {
lastpos= t->Pos;
WindowSystem::lasttime= t->At;
} else if (t->Code == eEvtNone) {
t->Flags= 0;
t->Pos= lastpos;
t->At= WindowSystem::lasttime;
}
// emergency exit :-)
if (t->IsKey() && t->Flags == (eFlgShiftKey|eFlgCntlKey|eFlgMetaKey)
&& t->MapToAscii() == 'u')
gSystem->Exit(1, FALSE);
if (WindowSystem::grabport && (WindowSystem::grabport != this)) {
switch (t->Code) {
case eEvtIdle:
case eEvtNone:
case eEvtLocMove:
case eEvtLocMoveBut:
case eEvtLocStill:
// ignore events
return;
case eEvtEnter:
case eEvtExit:
break;
default:
if (t->IsKey() || t->IsFunctionKey() || t->IsCursorKey())
WindowSystem::grabport->InputNotify(t);
else
WindowSystem::grabport->Bell(50);
return;
}
}
if (t->IsMouseButton()) {
if (WindowSystem::lastClick.DoubleClick(*t))
WindowSystem::Clicks++;
else
WindowSystem::Clicks= 1;
WindowSystem::lastClick= *t;
}
if (win)
win->InputNotify(t);
}
//---- Invalidation ------------------------------------------------------------
void WindowPort::InvalidateRect(const Rectangle &r, bool update)
{
if (state == eWsShown) {
if (inval == 0)
inval= new Region;
inval->Merge(r);
}
if (update)
gWindowSystem->Update();
}
void WindowPort::DevUpdate()
{
if (inval == 0 || inval->size <= 0)
return;
Region *old= inval;
inval= 0;
Rectangle *ir;
for (int i= 0; ir= old->GetAt(i); i++) {
UpdateRect(*ir);
GiveHint(eHintUnbatch, 0, 0);
}
delete old;
}
void WindowPort::UpdateRect(Rectangle &r)
{
if (win) {
Port *oldport= GrGetPort();
GrSetPort(this);
InitClip();
Clip(Inter(win->contentRect, r));
SetPenNormal();
SetInk(ePatBlack);
GiveHint(eHintBatch, sizeof(Rectangle), &r);
win->DrawAll(r, FALSE);
FlushMyText();
GrSetPort(oldport);
}
}
void WindowPort::FlushColorMap()
{
if (wcmap)
wcmap->Install(this);
}
void WindowPort::DevSetColor(RGBColor *cp)
{
u_long id= cp->GetId();
if (cp->TestFlag(eInkChanged)) {
if (cp->GetPrec() == 255) {
if (wcmap == WindowSystem::wcmap) {
wcmap= wcmap->MakeCopy(WindowSystem::wcmap);
wcmap->Ref();
}
id= wcmap->AllocateAndSetCell(id, cp->GetRGB(), this);
} else
id= wcmap->RGB2Index(cp->GetRGB());
cp->SetId(id);
cp->ResetFlag(eInkChanged);
}
DevSetColor2(id);
}
//---- cursor stuff ------------------------------------------------------------
GrCursor WindowPort::SetCursor(GrCursor c)
{
if (c != cursor && c >= eCrsNone && c <= eCrsUpDownArrow) {
GrCursor oldc= cursor;
cursor= c;
DevSetCursor(c);
return oldc;
}
return c;
}
GrCursor WindowPort::GetCursor()
{
return cursor;
}
GrCursor WindowPort::SetWaitCursor(unsigned int, GrCursor c)
{
c= SetCursor(c);
GiveHint(eHintWinBusy, 0, 0);
return c;
}
//---- input handling ----------------------------------------------------------
void WindowPort::GetEvent(Token *t, int timeout, bool overread)
{
if (havepushbacktoken) {
*t= pushbacktoken;
havepushbacktoken= FALSE;
} else
DevGetEvent(t, timeout, overread);
if (t->Code != eEvtNone && t->Code != eEvtIdle) {
lastpos= t->Pos;
WindowSystem::lasttime= t->At;
} else if (t->Code == eEvtNone) {
t->Pos= lastpos;
t->At= WindowSystem::lasttime;
}
};
void WindowPort::PushEvent(Token t)
{
if (t.Code != eEvtNone) {
pushbacktoken= t;
havepushbacktoken= TRUE;
}
}
//---- window management -------------------------------------------------------
void WindowPort::Hide()
{
if (state == eWsShown) {
FlushAnyText();
DevHide();
}
};
Point showdelta;
void WindowPort::Show(WindowPort *father, Rectangle r, bool block)
{
Point delta;
Rectangle rr= r;
if (state == eWsShown)
return;
SafeDelete(inval);
FlushAnyText();
if (father)
rr.origin+= father->GetRect().origin;
else if (r.origin == gPoint_1)
rr.origin= Half(WindowSystem::screenRect.extent - r.extent);
delta= rr.AmountToTranslateWithin(WindowSystem::screenRect);
rr.origin+= delta;
DevShow(father, rr);
showdelta= delta;
//if (delta != gPoint0)
// MoveMousePos(delta);
if (block) {
GrabLoop();
}
};
void WindowPort::Poll(int timeout)
{
WindowPort *oldgrabport= WindowSystem::grabport;
WindowSystem::grabport= this;
gSystem->InnerLoop(timeout);
WindowSystem::grabport= oldgrabport;
}
void WindowPort::GrabLoop()
{
exitloop= FALSE;
WindowPort *oldgrabport= WindowSystem::grabport;
WindowSystem::grabport= this;
do
gSystem->InnerLoop();
while (! exitloop);
WindowSystem::grabport= oldgrabport;
}
void WindowPort::Iconize()
{
DevIconize();
}
void WindowPort::Grab(bool g, bool fs)
{
if (fs) {
FlushAnyText();
WindowSystem::fullscreen= g;
}
DevGrab(g, fs);
}
void WindowPort::DevSetTitle(char*)
{
}
//---- graphic functions -------------------------------------------------------
void WindowPort::Scroll(Point delta)
{
Rectangle r1, rl[4], r(cliprect), oldclip= cliprect;
register int i, n;
bool doscroll, batchopen= FALSE;
FlushMyText();
r1= r + delta;
doscroll= r.Clip(r1);
n= Difference(rl, cliprect, r1);
if (0 && n == 1 && WindowSystem::batch && !overlay) {
UpdateRect(rl[0]);
batchopen= TRUE;
} else {
for (i= 0; i < n; i++)
InvalidateRect(rl[i]);
}
if (r.Clip(r1)) {
if (batchopen)
DevClip(oldclip);
DevScrollRect(r, delta);
}
if (batchopen)
GiveHint(eHintUnbatch, 0, 0);
DevUpdate();
}
bool WindowPort::DevImageCacheBegin(ImageCache *bb, Rectangle r)
{
if (WindowSystem::batch) {
if (scale & 2) {
DevClip(cliprect);
scale&= ~2;
}
FlushMyText();
r.origin += origin;
if (r.Clip(cliprect)) {
r.origin -= origin;
bb->r= r;
if (!bb->valid || !bb->vr.ContainsRect(r)) {
bb->vr= r;
if (bb->b == 0)
bb->b= new Bitmap(r.extent, gDepth);
return TRUE;
}
}
r.origin += origin;
batchInfo bi;
bi.b= bb->b->GetDevBitmap();
bi.r= r;
bi.p= bb->r.origin - bb->vr.origin;
DevGiveHint(eHintCacheStart, 0, &bi);
return FALSE;
}
return TRUE;
}
void WindowPort::DevImageCacheEnd(ImageCache *bb)
{
if (WindowSystem::batch) {
if (scale & 2) {
DevClip(cliprect);
scale&= ~2;
}
batchInfo bi;
bi.r= bb->vr;
bi.r.origin += origin;
if (bb->b == 0)
bb->b= new Bitmap(bi.r.extent, gDepth);
bi.b= bb->b->GetDevBitmap();
DevGiveHint(eHintCacheEnd, 0, &bi);
bb->valid= TRUE;
}
}
//---- abstract methods --------------------------------------------------------
void WindowPort::DevSetCursor(GrCursor)
{
AbstractMethod("DevSetCursor");
}
void WindowPort::DevScrollRect(Rectangle, Point)
{
AbstractMethod("DevScrollRect");
}
void WindowPort::DevHide()
{
AbstractMethod("DevHide");
}
void WindowPort::DevIconize()
{
AbstractMethod("DevIconize");
}
void WindowPort::DevShow(WindowPort*, Rectangle)
{
AbstractMethod("DevShow");
}
void WindowPort::DevGrab(bool, bool)
{
AbstractMethod("DevGrab");
}
void WindowPort::DevFullscreen(bool)
{
AbstractMethod("DevFullScreen");
}
void WindowPort::DevTop(bool)
{
AbstractMethod("DevTop");
};
void WindowPort::DevGetEvent(Token*, int, bool)
{
AbstractMethod("DevGetEvent");
};
void WindowPort::DevSetMousePos(Point, bool)
{
AbstractMethod("DevSetMousePos");
};
void WindowPort::DevSetColor2(u_long)
{
AbstractMethod("DevSetColor2");
}
void WindowPort::DevBell(long duration)
{
gWindowSystem->DevBell(duration);
}
Rectangle WindowPort::DevGetRect()
{
return portrect;
}
void WindowPort::DevSetExtent(Point e)
{
portrect.extent= e;
}
void WindowPort::DevSetOrigin(Point o)
{
portrect.origin= o;
}